import cv2
import numpy as np
from paddleocr import PaddleOCR
import math
import logging
import os

# 配置日志
logger = logging.getLogger(__name__)

class PaddleOcrSealDetector:
    """基于OpenCV和PaddleOCR的印章检测和识别类"""
    
    def __init__(self, use_handwritten=False):
        """初始化PaddleOCR模型"""
        try:
            # 初始化PaddleOCR（轻量模型，适配CPU，关闭调试日志）
            self.ocr = PaddleOCR(
                use_angle_cls=True,  # 角度检测
                lang="ch",           # 中文识别
                show_log=False       # 关闭详细日志
            )
            logger.info("PaddleOCR模型初始化成功")
            
            # 手写体识别功能
            self.use_handwritten = use_handwritten
            if use_handwritten:
                logger.info("PaddleOCR手写体识别功能已启用")
            
        except Exception as e:
            logger.error(f"PaddleOCR初始化失败：{str(e)}", exc_info=True)
            raise RuntimeError(f"PaddleOCR初始化异常，请检查环境：{str(e)}")

    def detect_seal_region(self, img_path):
        """
        印章区域检测：使用传统OpenCV方法检测印章
        返回：(图章区域列表, 原图, 红色掩码图)
        """
        # 1. 读取图片并校验
        img = cv2.imread(img_path)
        if img is None:
            error_msg = f"无法读取图片：路径错误或文件损坏（路径：{img_path}）"
            logger.error(error_msg)
            raise ValueError(error_msg)
        logger.info(f"成功读取图片，尺寸：{img.shape[0]}x{img.shape[1]}")

        # 2. 传统OpenCV方法检测
        opencv_regions = self._detect_seal_opencv(img, img_path)
        
        logger.info(f"OpenCV检测到印章区域总数：{len(opencv_regions)}")
        
        return opencv_regions, img, None

    def _detect_seal_opencv(self, img, img_path):
        """传统OpenCV方法检测印章，返回所有符合条件的区域"""
        # 颜色筛选：使用更宽松的红色检测范围
        hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
        # 扩大红色HSV范围：检测更多红色区域
        lower_red1 = np.array([0, 30, 30])  # 降低饱和度阈值
        upper_red1 = np.array([15, 255, 255])  # 扩大色相范围
        lower_red2 = np.array([165, 30, 30])  # 降低饱和度阈值
        upper_red2 = np.array([180, 255, 255])
        
        # 提取红色和蓝色区域掩码（印章可能是红色或蓝色）
        mask_red1 = cv2.inRange(hsv, lower_red1, upper_red1)
        mask_red2 = cv2.inRange(hsv, lower_red2, upper_red2)
        mask_red = cv2.bitwise_or(mask_red1, mask_red2)
        
        # 精确蓝色印章检测
        lower_blue = np.array([100, 50, 50])
        upper_blue = np.array([130, 255, 255])
        mask_blue = cv2.inRange(hsv, lower_blue, upper_blue)
        
        # 精确紫色印章检测
        lower_purple = np.array([130, 50, 50])
        upper_purple = np.array([160, 255, 255])
        mask_purple = cv2.inRange(hsv, lower_purple, upper_purple)
        
        # 合并红色、蓝色和紫色掩码
        mask_red = cv2.bitwise_or(mask_red, mask_blue)
        mask_red = cv2.bitwise_or(mask_red, mask_purple)
        
        # 保存红色掩码图（调试用）
        debug_path = os.path.join(os.path.dirname(img_path), "red_mask_debug.jpg")
        cv2.imwrite(debug_path, mask_red)
        logger.info(f"已生成红色掩码图：{debug_path}")

        # 形态学操作
        kernel = np.ones((7, 7), np.uint8)
        mask_red = cv2.morphologyEx(mask_red, cv2.MORPH_OPEN, kernel)
        mask_red = cv2.morphologyEx(mask_red, cv2.MORPH_CLOSE, kernel)

        # 轮廓筛选
        contours, _ = cv2.findContours(mask_red, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        seal_regions = []
        logger.info(f"OpenCV检测到轮廓数量：{len(contours)}")

        for idx, cnt in enumerate(contours):
            x, y, w, h = cv2.boundingRect(cnt)
            area = w * h
            img_area = img.shape[0] * img.shape[1]
            if area < 2000 or area > img_area * 0.3:
                logger.info(f"轮廓{idx}：{x},{y},{w},{h} 面积{area} 不在合理范围，过滤")
                continue

            # 圆形度检测
            (cx, cy), radius = cv2.minEnclosingCircle(cnt)
            circle_area = np.pi * radius * radius
            circularity = area / circle_area if circle_area > 0 else 0
            if not (0.5 < circularity < 1.5):
                logger.info(f"轮廓{idx}：圆形度{circularity:.2f}不在0.5~1.5范围，过滤")
                continue

            aspect_ratio = w / h
            if not (0.5 < aspect_ratio < 2.0):
                logger.info(f"轮廓{idx}：宽高比{aspect_ratio:.2f}（不在0.5~2.0），过滤")
                continue

            # 红色区域占比检测
            roi_mask = mask_red[y:y+h, x:x+w]
            red_ratio = cv2.countNonZero(roi_mask) / (w * h)
            if red_ratio < 0.2:
                logger.info(f"轮廓{idx}：红色占比{red_ratio:.2f} < 0.2，过滤")
                continue
                
            seal_regions.append((x, y, w, h))
            logger.info(f"轮廓{idx}：符合条件（面积{area}，{x},{y},{w},{h} 圆形度{circularity:.2f}，宽高比{aspect_ratio:.2f}）")

        # 返回所有符合条件的区域
        if seal_regions:
            # 在原图标注所有图章区域
            img_marked = img.copy()
            for i, (x, y, w, h) in enumerate(seal_regions):
                cv2.rectangle(img_marked, (x, y), (x + w, y + h), (0, 255, 0), 2)
                cv2.putText(img_marked, f"OpenCV-{i+1}", (x, y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1)
            
            # 如果启用了手写体识别，同时检测并标注手写体区域
            if self.use_handwritten:
                handwritten_regions = self.detect_handwritten_regions(img_path)
                if handwritten_regions:
                    # 使用绿色框标注手写体区域
                    for i, region in enumerate(handwritten_regions):
                        x, y, w, h = region['x'], region['y'], region['w'], region['h']
                        cv2.rectangle(img_marked, (x, y), (x + w, y + h), (0, 255, 0), 2)  # 绿色框
                        cv2.putText(img_marked, f"PaddleOCR-hand-{i+1}", (x, y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1)
                    logger.info(f"已标注{len(handwritten_regions)}个PaddleOCR手写体区域")
            
            marked_path = os.path.join(os.path.dirname(img_path), "seal_roi_marked.jpg")
            cv2.imwrite(marked_path, img_marked)
            logger.info(f"OpenCV已标注图章区域：{marked_path}（共{len(seal_regions)}个区域）")
            return seal_regions
        
        return []

    def recognize_seal_text(self, img_path, img, seal_regions):
        """
        识别多个印章区域的文字，使用传统OpenCV方法
        返回：识别结果列表
        """
        if not seal_regions:
            logger.warning("未检测到图章区域，无法识别文字")
            return []

        logger.info(f"开始识别{len(seal_regions)}个图章区域的文字")
        
        opencv_results = []
        
        for i, seal_region in enumerate(seal_regions):
            x, y, w, h = seal_region
            logger.info(f"处理印章区域{i+1}：x={x}, y={y}, w={w}, h={h}")

            # 裁剪图章区域（扩展边界，避免截断）
            expand = 20  # 扩展像素
            x_expand = max(0, x - expand)
            y_expand = max(0, y - expand)
            w_expand = min(img.shape[1] - x_expand, w + 2 * expand)
            h_expand = min(img.shape[0] - y_expand, h + 2 * expand)
            
            seal_img = img[y_expand:y_expand + h_expand, x_expand:x_expand + w_expand]
            logger.info(f"裁剪图章区域{i+1}：尺寸{seal_img.shape[1]}x{seal_img.shape[0]}（扩展后）")

            # 保存原始图章图像（调试用）
            seal_path = os.path.join(os.path.dirname(img_path), f"seal_preprocessed_{i+1}.jpg")
            cv2.imwrite(seal_path, seal_img)
            logger.info(f"已生成原始图章{i+1}：{seal_path}")

            # 传统OpenCV方法识别
            opencv_text = self._recognize_opencv_method(seal_img, img_path, i+1)
            if opencv_text:
                opencv_results.append({
                    "region": seal_region,
                    "text": opencv_text,
                    "method": "OpenCV"
                })
                logger.info(f"OpenCV识别结果{i+1}：{opencv_text}")

        return opencv_results

    def _recognize_opencv_method(self, seal_img, img_path, region_idx):
        """传统OpenCV方法识别印章文字"""
        try:
            # 提取红色印章内容（只识别红色部分，排除黑色文字）
            hsv = cv2.cvtColor(seal_img, cv2.COLOR_BGR2HSV)
            # 红色HSV范围
            lower_red1 = np.array([0, 43, 46])
            upper_red1 = np.array([10, 255, 255])
            lower_red2 = np.array([156, 43, 46])
            upper_red2 = np.array([180, 255, 255])
            
            # 创建红色掩码
            mask_red1 = cv2.inRange(hsv, lower_red1, upper_red1)
            mask_red2 = cv2.inRange(hsv, lower_red2, upper_red2)
            red_mask = cv2.bitwise_or(mask_red1, mask_red2)
            
            # 只保留红色区域
            red_seal = cv2.bitwise_and(seal_img, seal_img, mask=red_mask)
            
            # 保存红色印章图像（调试用）
            red_seal_path = os.path.join(os.path.dirname(img_path), f"red_seal_debug_{region_idx}.jpg")
            cv2.imwrite(red_seal_path, red_seal)
            logger.info(f"已生成红色印章图像{region_idx}：{red_seal_path}")

            # 使用PaddleOCR识别红色印章内容
            ocr_result = self.ocr.ocr(red_seal, cls=True)
            if ocr_result and ocr_result[0]:
                # 提取文字和置信度
                texts = []
                confidences = []
                for line in ocr_result[0]:
                    if len(line) >= 2:
                        text = line[1][0] if isinstance(line[1], (list, tuple)) else str(line[1])
                        confidence = line[1][1] if isinstance(line[1], (list, tuple)) and len(line[1]) > 1 else 0.0
                        if text.strip():
                            texts.append(text.strip())
                            confidences.append(confidence)
                
                if texts:
                    # 按置信度排序
                    sorted_results = sorted(zip(texts, confidences), key=lambda x: x[1], reverse=True)
                    best_text = sorted_results[0][0]
                    best_confidence = sorted_results[0][1]
                    logger.info(f"OpenCV红色印章识别结果{region_idx}：{best_text}，置信度：{best_confidence:.2f}")
                    return best_text
                else:
                    logger.warning(f"OpenCV红色印章区域{region_idx}未识别到文字")
                    return ""
            else:
                logger.warning(f"OpenCV PaddleOCR未返回有效结果{region_idx}")
                return ""
        except Exception as e:
            logger.error(f"OpenCV识别失败{region_idx}：{str(e)}")
            return ""

    def recognize_full_text(self, img_path):
        """识别图片中的全部文字"""
        img = cv2.imread(img_path)
        if img is None:
            return "无法读取图片以识别全部内容"
            
        try:
            result = self.ocr.ocr(img_path)
            if not result or len(result) == 0 or not result[0]:
                return "未识别到任何文字"
            
            full_text = " ".join([line[1][0] for line in result[0]])
            return full_text
        except Exception as e:
            logger.error(f"全文识别失败：{str(e)}")
            return "全文识别失败"

    def _sort_circular_text(self, text_info, img_shape):
        """辅助方法：按环形排列矫正文字顺序（顺时针）"""
        if len(text_info) <= 1:
            return [t[0] for t in text_info]

        # 计算图章中心（取所有文字区域的中心平均值）
        centers = []
        for text, coords in text_info:
            # 文字区域四边形的中心坐标
            try:
                cx = sum(p[0] for p in coords) / 4
                cy = sum(p[1] for p in coords) / 4
                centers.append((cx, cy))
            except (TypeError, ValueError) as e:
                logger.warning(f"计算文字中心失败：{e}，跳过该文字")
                continue

        if not centers:
            return [t[0] for t in text_info]

        # 图章整体中心
        center_x = sum(cx for cx, cy in centers) / len(centers)
        center_y = sum(cy for cx, cy in centers) / len(centers)
        logger.debug(f"图章中心坐标：({center_x:.1f}, {center_y:.1f})")

        # 按文字中心相对于图章中心的角度排序（顺时针）
        def get_angle(text_item):
            text, coords = text_item
            try:
                cx = sum(p[0] for p in coords) / 4
                cy = sum(p[1] for p in coords) / 4
                # 计算角度（弧度转角度，调整为顺时针排序）
                angle_rad = math.atan2(cy - center_y, cx - center_x)
                angle_deg = math.degrees(angle_rad)
                return (angle_deg + 360) % 360  # 转为0~360度
            except (TypeError, ValueError) as e:
                logger.warning(f"计算角度失败：{e}，使用默认角度")
                return 0  # 给错误坐标一个默认角度

        # 按角度排序并提取文字
        sorted_items = sorted(text_info, key=get_angle)
        return [item[0] for item in sorted_items]

    def _preprocess_handwritten_image(self, img):
        """手写体图像预处理，提高识别效果"""
        try:
            # 1. 转换为灰度图
            gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
            
            # 2. 增强对比度
            clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
            enhanced = clahe.apply(gray)
            
            # 3. 去噪
            denoised = cv2.medianBlur(enhanced, 3)
            
            # 4. 二值化（自适应阈值）
            binary = cv2.adaptiveThreshold(
                denoised, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2
            )
            
            # 5. 形态学操作，连接断裂的笔画
            kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (2, 2))
            morphed = cv2.morphologyEx(binary, cv2.MORPH_CLOSE, kernel)
            
            # 6. 转换回BGR格式
            processed_img = cv2.cvtColor(morphed, cv2.COLOR_GRAY2BGR)
            
            logger.info("手写体图像预处理完成")
            return processed_img
            
        except Exception as e:
            logger.warning(f"手写体图像预处理失败：{str(e)}")
            return img

    def _is_handwritten_text(self, img_crop, text, coords):
        try:
            # 1. 基本尺寸调整：放宽最小尺寸（工整手写体可能更小）
            h, w = img_crop.shape[:2]
            if w < 10 or h < 5 or w > 800 or h > 300:  # 放宽尺寸范围
                return False
            
            # 2. 文字长度调整：允许1~30字（覆盖短文本）
            text_len = len(text.strip())
            if text_len < 1 or text_len > 30:
                return False
            
            # 3. 中文占比调整：必须包含中文（“以上信息相符”是中文，排除纯数字/字母）
            chinese_chars = sum(1 for char in text if '\u4e00' <= char <= '\u9fff')
            if chinese_chars / text_len < 0.5:  # 中文占比≥50%
                return False
            
            # 4. 图像特征调整：降低工整手写体的判断阈值
            gray = cv2.cvtColor(img_crop, cv2.COLOR_BGR2GRAY)
            edges = cv2.Canny(gray, 80, 200)  # 提高Canny阈值，减少工整手写体的边缘噪声
            edge_density = np.sum(edges > 0) / (w * h)
            
            # 轮廓复杂度：工整手写体轮廓数少，降低阈值（≥1即可）
            contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
            contour_complexity = len(contours)
            
            # 凸包比例：工整手写体更规则，放宽阈值（≥0.7即可）
            avg_hull_ratio = 1.0
            if len(contours) > 0:
                hull_areas = []
                for contour in contours:
                    if cv2.contourArea(contour) > 5:  # 放宽小轮廓过滤
                        hull = cv2.convexHull(contour)
                        hull_area = cv2.contourArea(hull)
                        contour_area = cv2.contourArea(contour)
                        if hull_area > 0:
                            hull_areas.append(contour_area / hull_area)
                if hull_areas:
                    avg_hull_ratio = np.mean(hull_areas)
            
            # 5. 评分调整：降低阈值至3分（原4分），适配工整手写体
            handwritten_score = 0
            # 边缘密度：工整手写体边缘密度低，0.05~0.3即可加分
            if 0.05 <= edge_density <= 0.3:
                handwritten_score += 2
            elif 0.02 <= edge_density <= 0.5:
                handwritten_score += 1
            # 轮廓复杂度：≥1即可加分（原≥3）
            if contour_complexity >= 1:
                handwritten_score += 2
            # 凸包比例：≥0.7即可加分（原<0.8）
            if avg_hull_ratio >= 0.7:
                handwritten_score += 2
            # 中文占比：≥50%加分
            if chinese_chars / text_len >= 0.5:
                handwritten_score += 1
            
            # 6. 判定：评分≥3即为手写体（原≥4）
            is_handwritten = handwritten_score >= 3
            logger.debug(f"手写体检测: 文字='{text}', 边缘密度={edge_density:.3f}, 轮廓数={contour_complexity}, 凸包比={avg_hull_ratio:.3f}, 评分={handwritten_score}, 结果={is_handwritten}")
            return is_handwritten
        except Exception as e:
            logger.warning(f"手写体特征检测失败：{str(e)}")
            return False

    def _calculate_handwritten_score(self, img_crop, text):
        """计算手写体评分"""
        try:
            h, w = img_crop.shape[:2]
            if w < 15 or h < 8:
                return 0
            
            # 转换为灰度图
            gray = cv2.cvtColor(img_crop, cv2.COLOR_BGR2GRAY)
            
            # 计算边缘密度
            edges = cv2.Canny(gray, 50, 150)
            edge_density = np.sum(edges > 0) / (w * h)
            
            # 计算轮廓复杂度
            contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
            contour_complexity = len(contours)
            
            # 计算凸包比例
            if len(contours) > 0:
                hull_areas = []
                for contour in contours:
                    if cv2.contourArea(contour) > 10:
                        hull = cv2.convexHull(contour)
                        hull_area = cv2.contourArea(hull)
                        contour_area = cv2.contourArea(contour)
                        if hull_area > 0:
                            hull_areas.append(contour_area / hull_area)
                
                if hull_areas:
                    avg_hull_ratio = np.mean(hull_areas)
                else:
                    avg_hull_ratio = 1.0
            else:
                avg_hull_ratio = 1.0
            
            # 计算评分
            score = 0
            
            # 边缘密度评分
            if 0.1 <= edge_density <= 0.4:
                score += 3
            elif 0.05 <= edge_density <= 0.6:
                score += 2
            elif 0.02 <= edge_density <= 0.8:
                score += 1
            
            # 轮廓复杂度评分
            if contour_complexity >= 5:
                score += 3
            elif contour_complexity >= 3:
                score += 2
            elif contour_complexity >= 1:
                score += 1
            
            # 凸包比例评分
            if avg_hull_ratio < 0.7:
                score += 3
            elif avg_hull_ratio < 0.8:
                score += 2
            elif avg_hull_ratio < 0.9:
                score += 1
            
            # 文字内容评分
            chinese_chars = sum(1 for char in text if '\u4e00' <= char <= '\u9fff')
            if chinese_chars > 0:
                score += 2
            
            # 文字长度评分（手写体通常较短）
            if 1 <= len(text.strip()) <= 10:
                score += 1
            elif 11 <= len(text.strip()) <= 20:
                score += 0.5
            
            return score
            
        except Exception as e:
            logger.warning(f"手写体评分计算失败：{str(e)}")
            return 0

    def detect_handwritten_regions(self, img_path):
        """检测手写体区域"""
        if not self.use_handwritten:
            logger.info("手写体识别未启用")
            return []
        try:
            img = cv2.imread(img_path)
            if img is None:
                logger.error("无法读取图片")
                return []
            
            # 1. 轻度预处理：减少对工整手写体的特征破坏
            gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
            clahe = cv2.createCLAHE(clipLimit=1.5, tileGridSize=(8,8))  # 降低对比度增强强度
            enhanced = clahe.apply(gray)
            processed_img = cv2.cvtColor(enhanced, cv2.COLOR_GRAY2BGR)  # 不进行二值化，保留更多特征
            
            # 2. 全文识别：获取所有文本区域（含手写体）
            ocr_result = self.ocr.ocr(processed_img, cls=True)
            if not ocr_result or not ocr_result[0]:
                logger.info("PaddleOCR未检测到文字区域")
                return []
            
            handwritten_regions = []
            for i, line in enumerate(ocr_result[0]):
                if len(line) >= 2:
                    coords = line[0]
                    text_info = line[1]
                    text = text_info[0] if isinstance(text_info, (list, tuple)) else str(text_info)
                    confidence = text_info[1] if isinstance(text_info, (list, tuple)) and len(text_info) > 1 else 0.0
                    
                    # 3. 提取边界框：确保覆盖完整文字
                    x_coords = [int(point[0]) for point in coords]
                    y_coords = [int(point[1]) for point in coords]
                    x_min, x_max = min(x_coords), max(x_coords)
                    y_min, y_max = min(y_coords), max(y_coords)
                    width = x_max - x_min
                    height = y_max - y_min
                    
                    # 4. 基本过滤：仅过滤极小区域和低置信度
                    if confidence >= 0.3 and width >= 10 and height >= 5 and len(text.strip()) >= 1:
                        # 5. 裁剪区域并判断是否为手写体（使用修改后的_is_handwritten_text）
                        x_min = max(0, x_min - 5)  # 轻微扩展，避免截断
                        y_min = max(0, y_min - 5)
                        x_max = min(img.shape[1], x_max + 5)
                        y_max = min(img.shape[0], y_max + 5)
                        img_crop = img[y_min:y_max, x_min:x_max]
                        
                        if self._is_handwritten_text(img_crop, text.strip(), coords):
                            handwritten_regions.append({
                                'region_id': i + 1,
                                'x': x_min,
                                'y': y_min,
                                'w': x_max - x_min,
                                'h': y_max - y_min,
                                'detection_confidence': confidence,
                                'text': text.strip(),
                                'recognition_confidence': confidence
                            })
                            logger.info(f"检测到工整手写体区域{i+1}: 位置({x_min},{y_min}), {confidence} 内容: {text.strip()}")
            
            return handwritten_regions[:3]  # 取前3个高置信度区域
        except Exception as e:
            logger.warning(f"PaddleOCR手写体检测失败：{str(e)}")
            return []


    def recognize_handwritten_text(self, img, handwritten_regions):
        """识别手写体文字内容"""
        if not self.use_handwritten or not handwritten_regions:
            return handwritten_regions
            
        try:
            logger.info("使用PaddleOCR识别手写体文字...")
            
            # 手写体图像预处理
            processed_img = self._preprocess_handwritten_image(img)
            
            for region in handwritten_regions:
                try:
                    # 裁剪手写体区域
                    x, y, w, h = region['x'], region['y'], region['w'], region['h']
                    
                    # 扩展边界，避免截断
                    expand = 10
                    x_expand = max(0, x - expand)
                    y_expand = max(0, y - expand)
                    w_expand = min(processed_img.shape[1] - x_expand, w + 2 * expand)
                    h_expand = min(processed_img.shape[0] - y_expand, h + 2 * expand)
                    
                    handwritten_crop = processed_img[y_expand:y_expand + h_expand, x_expand:x_expand + w_expand]
                    
                    # 使用PaddleOCR识别手写体内容
                    ocr_result = self.ocr.ocr(handwritten_crop, cls=True)
                    
                    if ocr_result and ocr_result[0]:
                        # 提取识别结果
                        texts = []
                        confidences = []
                        for line in ocr_result[0]:
                            if len(line) >= 2:
                                text = line[1][0] if isinstance(line[1], (list, tuple)) else str(line[1])
                                confidence = line[1][1] if isinstance(line[1], (list, tuple)) and len(line[1]) > 1 else 0.0
                                if text.strip() and confidence >= 0.2:  # 过滤低置信度结果
                                    texts.append(text.strip())
                                    confidences.append(confidence)
                        
                        if texts:
                            # 选择置信度最高的结果
                            best_idx = confidences.index(max(confidences))
                            best_text = texts[best_idx]
                            best_confidence = confidences[best_idx]
                            
                            # 更新区域信息
                            region['text'] = best_text
                            region['recognition_confidence'] = best_confidence
                            
                            logger.info(f"手写体区域{region['region_id']}识别结果: {best_text}, 置信度: {best_confidence:.3f}")
                        else:
                            logger.warning(f"手写体区域{region['region_id']}未识别到有效文字")
                            region['text'] = ""
                            region['recognition_confidence'] = 0.0
                    else:
                        logger.warning(f"手写体区域{region['region_id']}OCR识别失败")
                        region['text'] = ""
                        region['recognition_confidence'] = 0.0
                        
                except Exception as e:
                    logger.warning(f"手写体区域{region['region_id']}识别异常: {str(e)}")
                    region['text'] = ""
                    region['recognition_confidence'] = 0.0
            
            # 过滤掉没有识别出内容的区域
            valid_regions = [region for region in handwritten_regions if region.get('text', '').strip()]
            
            logger.info(f"有效手写体区域数量: {len(valid_regions)}")
            return valid_regions
            
        except Exception as e:
            logger.warning(f"PaddleOCR手写体识别失败：{str(e)}")
            return handwritten_regions

    def visualize_handwritten_regions(self, img, handwritten_regions, img_path):
        """可视化手写体区域"""
        if not self.use_handwritten or not handwritten_regions:
            return None
            
        try:
            # 创建标注图像
            img_marked = img.copy()
            
            # 定义颜色（蓝色用于手写体）
            color = (255, 0, 0)  # 蓝色
            
            for i, region in enumerate(handwritten_regions):
                x, y, w, h = region['x'], region['y'], region['w'], region['h']
                detection_conf = region['detection_confidence']
                recognition_conf = region.get('recognition_confidence', 0.0)
                text = region.get('text', '')
                
                # 绘制矩形框
                cv2.rectangle(img_marked, (x, y), (x + w, y + h), color, 2)
                
                # 添加标签
                label = f"PaddleOCR-hand{i+1}: {text[:10]}..." if len(text) > 10 else f"PaddleOCR-hand{i+1}: {text}"
                cv2.putText(img_marked, label, (x, y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 1)
                
                # 添加置信度信息
                conf_label = f" {detection_conf:.3f} {recognition_conf:.3f}"
                cv2.putText(img_marked, conf_label, (x, y+h+20), cv2.FONT_HERSHEY_SIMPLEX, 0.4, color, 1)
            
            # 保存标注图像
            marked_path = os.path.join(os.path.dirname(img_path), "paddleocr_handwritten_marked.jpg")
            cv2.imwrite(marked_path, img_marked)
            logger.info(f"PaddleOCR手写体区域已标注到：{marked_path}")
            
            return marked_path
            
        except Exception as e:
            logger.warning(f"PaddleOCR手写体可视化失败：{str(e)}")
            return None


if __name__ == "__main__":
    import sys
    
    if len(sys.argv) < 2:
        print("使用方法: python PaddleOcrSealDetector.py <图片路径> [--handwritten]")
        print("")
        print("示例:")
        print("  python PaddleOcrSealDetector.py image.jpg")
        print("  python PaddleOcrSealDetector.py image.jpg --handwritten")
        print("")
        print("功能说明:")
        print("  - 使用OpenCV检测印章区域")
        print("  - 使用PaddleOCR识别印章文字")
        print("  - 支持全文识别")
        print("  - 支持手写体识别（可选）")
        print("  - 生成调试图像：red_mask_debug.jpg, seal_roi_marked.jpg, seal_preprocessed_*.jpg")
        print("  - 手写体标注图像：paddleocr_handwritten_marked.jpg")
        sys.exit(1)
    
    img_path = sys.argv[1]
    use_handwritten = "--handwritten" in sys.argv
    
    print("=" * 60)
    print("PaddleOcrSealDetector 印章识别演示")
    print("=" * 60)
    print(f"图片路径: {img_path}")
    print("使用技术: OpenCV + PaddleOCR")
    if use_handwritten:
        print("手写体识别: 已启用")
    print("=" * 60)
    
    try:
        # 创建检测器
        detector = PaddleOcrSealDetector(use_handwritten=use_handwritten)
        
        # 1. 检测印章区域
        print("\n1. 检测印章区域...")
        seal_regions, img, red_mask = detector.detect_seal_region(img_path)
        
        if seal_regions:
            print(f"✅ 检测到 {len(seal_regions)} 个印章区域")
            for i, (x, y, w, h) in enumerate(seal_regions):
                print(f"   区域{i+1}: 位置({x},{y}), 尺寸({w}x{h})")
        else:
            print("❌ 未检测到印章区域")
        
        # 2. 识别印章文字
        print("\n2. 识别印章文字...")
        if seal_regions:
            recognition_results = detector.recognize_seal_text(img_path, img, seal_regions)
            
            if recognition_results:
                print("✅ 印章文字识别结果:")
                for i, result in enumerate(recognition_results):
                    region = result["region"]
                    text = result["text"]
                    method = result["method"]
                    x, y, w, h = region
                    print(f"   区域{i+1} ({method}): {text}")
                    print(f"     位置: ({x},{y}), 尺寸: ({w}x{h})")
            else:
                print("❌ 未识别到印章文字")
        
        # 3. 全文识别
        print("\n3. 全文识别...")
        full_text = detector.recognize_full_text(img_path)
        if full_text and full_text != "未识别到任何文字":
            print("✅ 全文识别结果:")
            print(f"   {full_text[:100]}{'...' if len(full_text) > 100 else ''}")
        else:
            print("❌ 未识别到文字内容")
        
        # 4. 手写体识别（如果启用）
        if use_handwritten:
            print("\n4. 手写体检测和识别...")
            handwritten_regions = detector.detect_handwritten_regions(img_path)
            
            if handwritten_regions:
                print(f"✅ 检测到 {len(handwritten_regions)} 个手写体区域")
                
                # 识别手写体文字
                handwritten_regions = detector.recognize_handwritten_text(img, handwritten_regions)
                
                # 可视化手写体区域
                detector.visualize_handwritten_regions(img, handwritten_regions, img_path)
                
                print("✅ 手写体识别结果:")
                for region in handwritten_regions:
                    x, y, w, h = region['x'], region['y'], region['w'], region['h']
                    text = region.get('text', '')
                    detection_conf = region['detection_confidence']
                    recognition_conf = region.get('recognition_confidence', 0.0)
                    print(f"   区域{region['region_id']}: {text}")
                    print(f"     位置: ({x},{y}), 尺寸: ({w}x{h})")
                    print(f"     检测置信度: {detection_conf:.3f}, 识别置信度: {recognition_conf:.3f}")
            else:
                print("❌ 未检测到手写体区域")
        
        # 5. 生成的文件
        print("\n5. 生成的调试文件:")
        debug_files = [
            "red_mask_debug.jpg",
            "seal_roi_marked.jpg"
        ]
        
        # 检查seal_preprocessed文件
        import glob
        seal_files = glob.glob(os.path.join(os.path.dirname(img_path), "seal_preprocessed_*.jpg"))
        debug_files.extend([os.path.basename(f) for f in seal_files])
        
        # 检查手写体标注文件
        if use_handwritten:
            debug_files.append("paddleocr_handwritten_marked.jpg")
        
        for file in debug_files:
            file_path = os.path.join(os.path.dirname(img_path), file)
            if os.path.exists(file_path):
                print(f"   ✅ {file}")
            else:
                print(f"   ❌ {file} (未生成)")
        
        print("\n" + "=" * 60)
        print("识别完成！")
        print("=" * 60)
        
    except Exception as e:
        print(f"\n❌ 识别过程出错: {str(e)}")
        import traceback
        traceback.print_exc()
        sys.exit(1)
